<?php 
class Google_Gdata_Request
{
    const GET = 'GET';
    
    const POST = 'POST';
    
    const PUT = 'PUT';
    
    const DELETE = 'DELETE';
    
    protected $_url;
    
    protected $_method;
    
    protected $_consumerKey;
    
    protected $_consumerSecret;
    
    protected $_requestorId;
    
    protected $_params = array();
    
    protected $client = null;
    
    public function setUrl($url)
    {
        $this->_url = $url;
        return $this;
    }
    
    public function setRequestorId($requestorId)
    {
        $this->_requestorId = $requestorId;
        return $this;
    }

    public function setMethod($method)
    {
        $this->_method = $method;
        return $this;
    }

    public function setConsumerKey($consumerKey)
    {
        $this->_consumerKey = $consumerKey;
        return $this;
    }

    public function setConsumerSecret($consumerSecret)
    {
        $this->_consumerSecret = $consumerSecret;
        return $this;
    }  
    
    public function setParams(array $params)
    {
        $this->_params = array_merge($this->_params, $params);
        return $this;
    }

    public function send()
    {
        $oauthArgs = array(
            'oauth_version'          => '1.0',
            'oauth_nonce'            => md5(microtime() . mt_rand()),
            'oauth_timestamp'        => time(),
            'oauth_consumer_key'     => $this->_consumerKey,
            'oauth_signature_method' => 'HMAC-SHA1'
        );
        
        $this->_params['xoauth_requestor_id'] = $this->_requestorId;
        
        $consumer = new Oauth_Consumer($this->_consumerKey, $this->_consumerSecret, null);
        
        $request = Oauth_Request::fromConsumerAndToken($consumer, NULL, $this->_method, $this->_url, $this->_params);
        
        $request->signRequest(new Oauth_Signature_Method_HMACSHA1(), $consumer, null);  

        $url = $this->_url . '?' . $this->implodeAssoc('=', '&', $this->_params);
                  
        $this->_client = new Zend_Http_Client();
        $this->_client->setConfig(array('keepalive' => true, 'timeout' => 300));
        
        $this->_client->setMethod($request->getNormalizedHttpMethod());
        $this->_client->setUri($url);
        $this->_client->setHeaders('GData-Version: 3.0');
        $this->_client->setHeaders($request->toHeader());      
        
        $response = $this->_client->request();
        
        if ($response->getStatus() == "200") {
            return $response->getBody();
        } else {
            throw new Ot_Exception('Error executing remote API call: ' . $response->getBody());
        }        
    }
    
    protected function implodeAssoc($inner_glue, $outer_glue, $array) 
    {  
        $output = array();  
        foreach($array as $key => $item) {  
            $output[] = $key . $inner_glue . urlencode($item);  
        }  
        return implode($outer_glue, $output);  
    }  
    
    protected function paramsToString($params)
    {
        // Urlencode both keys and values
        $keys = Oauth_Util::urlencodeRfc3986(array_keys($params));
        $values = Oauth_Util::urlencodeRfc3986(array_values($params));
        $params = array_combine($keys, $values);
        
        // Sort by keys (natsort)
        uksort($params, 'strcmp');
        
        // Generate key=value pairs
        $pairs = array();
        foreach ($params as $key =>$value ) {
            if (is_array($value)) {
                // If the value is an array, it's because there are multiple 
                // with the same key, sort them, then add all the pairs
                natsort($value);
                foreach ($value as $v2) {
                    $pairs[] = $key . '=' . $v2;
                }
            } else {
                $pairs[] = $key . '=' . $value;
            }
        }
            
        // Return the pairs, concated with &
        return implode('&', $pairs);        
    }
}